//
//  HDRCloud.m
//  MyClouds
//
//  Created by sarah doo on 13-8-7.
//  Copyright (c) 2013年 sarah doo. All rights reserved.
//

#import "HDRCloud.h"

@implementation HDRCloud

@synthesize signture, version, crc, cmd, length, HDRData, receiveCRC;

- (id)init {
    self = [super init];
    if (self) {
        self.crc = 0;
//        char buffer[16];
        //sprintf(buffer,"%s%c%c%c%c%c","cPxS",0x00010000,0,0x00000001,self.length,0);
        //self.crc = CRCTest(buffer, 20);
        self.signture = @"cPxS";
        
        NSArray *array = [NSArray arrayWithObjects:@"0x00010000", [NSString stringWithFormat:@"%d", self.crc], @"0x00000001", @"20", nil];
        NSMutableData *data = [NSMutableData dataWithData:[self changeToDate:array]];
        NSData *signtureData = [self.signture dataUsingEncoding:NSUTF8StringEncoding];
//        NSLog(@"signtureData --- %@",signtureData);
        NSMutableData *mutableData = [NSMutableData dataWithData:signtureData];
        [mutableData appendData:data];
        
        int versions = 0x00010000;
        int cmds = 0x00000001;
        int crcs = 0;
        int lengths = 20;
        NSData *versionData = [NSData dataWithBytes:&versions length:sizeof(versions)];
        NSData *cmdData = [NSData dataWithBytes:&cmds length:sizeof(cmds)];
        NSData *crcsData = [NSData dataWithBytes:&crcs length:sizeof(crcs)];
        NSData *lengthsData = [NSData dataWithBytes:&lengths length:sizeof(lengths)];
        NSData *singData = [self.signture dataUsingEncoding:NSUTF8StringEncoding];
        NSData *sing = [self sortData:singData];
        self.crc = [self crcs:mutableData withLength:20];
//        NSLog(@"crc%d",self.crc);
        NSMutableData *testData = [NSMutableData dataWithCapacity:20];
        [testData appendData:sing];
        [testData appendData:versionData];
        [testData appendData:crcsData];
        [testData appendData:cmdData];
        [testData appendData:lengthsData];
        self.crc = [self crcs:testData withLength:20];

    }
    return self;
}

- (NSData *)HDRData {
    int version = 0x00010000;
    int cmd = 0x00000001;
    int crcs = self.crc;
    int lengths = 20;

    NSData *versionData = [NSData dataWithBytes:&version length:sizeof(version)];
    NSData *cmdData = [NSData dataWithBytes:&cmd length:sizeof(cmd)];
    NSData *crcsData = [NSData dataWithBytes:&crcs length:sizeof(crcs)];
    NSData *lengthsData = [NSData dataWithBytes:&lengths length:sizeof(lengths)];
    NSData *singData = [self.signture dataUsingEncoding:NSUTF8StringEncoding];
    NSData *sing = [self sortData:singData];
    NSMutableData *testData = [NSMutableData dataWithCapacity:20];
    [testData appendData:sing];
    [testData appendData:versionData];
    [testData appendData:crcsData];
    [testData appendData:cmdData];
    [testData appendData:lengthsData];
    return testData;
}

int CRCTest(char *p, int length)
{
	register unsigned char l, h, t;
	l = h = 0xff;
	for ( int i = 0; i < length; i++ )
	{
		h^= p[i];
		h^= h>>4;
		t = h;
		h = l;
		l = t;
		t = (l << 4) | (l >> 4);
		h^= ((t << 2) | (t >> 6)) & 0x1f;
		h^= t & 0xf0;
		l^= ((t << 1) | (t >> 7)) & 0xe0;
	}
	return ((int)h<<8) | l;
}

- (int)crcs:(NSData *)da withLength:(int)lengths{
    int l, h, t;
    l = 0x000000ff;
    h = 0x000000ff;
    Byte *data = (Byte *)[da bytes];
    for (int i = 0; i < lengths; i++) {
        h ^= data[i];
        h &= 0x000000ff;
        h ^= h >> 4;
        h &= 0x000000ff;
        t = h;
        h = l;
        l = t;
        t = ((l << 4) | (l >> 4));
        t &= 0x000000ff;
        h ^= ((t << 2) | (t >> 6)) & 0x0000001f;
        h &= 0x000000ff;
        h ^= t & 0x000000f0;
        h &= 0x000000ff;
        l ^= ((t << 1) | (t >> 7)) & 0x000000e0;
        l &= 0x000000ff;
    }
    h &= 0x000000ff;
    l &= 0x000000ff;
    return (h << 8) | l;
}


- (NSData *)changeToDate:(NSArray *)datas{
    int z = 0x00000001;
    NSData * date = [NSData dataWithBytes:&z length:sizeof(z)];
    NSLog(@"date ----- y   %@", date);
    return date;
}

- (NSData *)sortData:(NSData *)data {
    Byte *byte = (Byte *)[data bytes];
    NSMutableData *last = [NSMutableData dataWithCapacity:10];
    for (int i = [data length] - 1; i >= 0; i--) {
        Byte x = byte[i];
        NSData *data = [NSData dataWithBytes:&x length:sizeof(x)];
        [last appendData:data];
    }
    NSLog(@"last ----- %@", last);
    return last;
}
- (NSString *)stringFromHexString:(NSString *)hexString {
    char *myBuffer = (char *)malloc((int)[hexString length] / 2 + 1);
    bzero(myBuffer, [hexString length] / 2 + 1);
    for (int i = 0; i < [hexString length] - 1; i += 2) {
        unsigned int anInt;
        NSString * hexCharStr = [hexString substringWithRange:NSMakeRange(i, 2)];
        NSScanner * scanner = [[[NSScanner alloc] initWithString:hexCharStr] autorelease];
        [scanner scanHexInt:&anInt];
        myBuffer[i / 2] = (char)anInt;
    }
    NSString *unicodeString = [NSString stringWithCString:myBuffer encoding:4];
    NSLog(@"string ----- %@",unicodeString);
    return unicodeString;
}
- (void)dealloc {
    self.signture = nil;
    self.version = nil;
    self.cmd = nil;
    [super dealloc];
}

- (NSString *)dataToString:(NSData *)data {
    NSRange range;
    range.location = 0;
    range.length = 4;
    NSData *da = [data subdataWithRange:range];
    NSString *test = [[NSString alloc] initWithData:da encoding:NSUTF8StringEncoding];
//    NSLog(@"string --------- %@",test);
    return [test autorelease];
}

- (int)byteToInt:(NSData *)p {
    int y = 4;
    for (int i = 1 * y; i < [p length]/4; i += 4) {
        NSRange range;
        range.location = i;
        NSLog(@"z ---- %d",i);
        range.length = 4;
        NSData *data = [p subdataWithRange:range];
        NSLog(@"NSData ------ %@",data);
        int temp;
        Byte *b=(Byte *)[data bytes];
        temp = (b[0] & 0xff)| (b[1] & 0xff) << 8 | (b[2] & 0xff) << 16 | (b[3] & 0xff) << 24;
        NSLog(@"changToInt ------------ > %d", temp);
        if (i == 8) {
            self.crc = temp;
        }
    }
    return 0;
}

- (int)dataToInt:(NSData *)p {
    int temp;
    Byte *b=(Byte *)[p bytes];
    temp = (b[0] & 0xff)| (b[1] & 0xff) << 8 | (b[2] & 0xff) << 16 | (b[3] & 0xff) << 24;
    NSLog(@"changToInt ------------ > %d", temp);
    return temp;
}

- (BOOL)verifyCRC:(NSData *)data {
    NSRange range ;
    range.location = 8;
    range.length = 4;
    NSData *crcData = [data subdataWithRange:range];
    NSLog(@"crcData ------ %@",crcData);
    int verifyC = [self dataToInt:crcData];
    int x = 0;
    NSData *crcDatas = [NSData dataWithBytes:&x length:sizeof(x)];
    range.location = 0;
    range.length = 8;
    NSData *before = [data subdataWithRange:range];
    NSMutableData *lastData = [NSMutableData dataWithData:before];
    [lastData appendData:crcDatas];
    range.location = 12;
    range.length = data.length - 12;
    NSData *later = [data subdataWithRange:range];
    [lastData appendData:later];
    int newCRC = [self crcs:lastData withLength:[data length]];
    NSLog(@"newCRC --- %d, verifyC ---- %d", newCRC, verifyC);
    NSLog(@"verity data ---------- %@", data);
    NSLog(@"laster data ----------- %@", lastData);
    if (verifyC == newCRC) {
        return YES;
    } else {
        return NO;
    }
}

@end
